﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Log;
using Managers;
using Managers.FileTransfer.Client;
using Managers.FileTransfer.Server;
using Managers.LiveControl.Server;
using Managers.Nova.Server;
using Model.Extensions;
using Network;
using Providers.LiveControl.Server;
using Providers.Nova.Modules;
using static Providers.LiveControl.Server.WindowApi;
using Message = System.Windows.Forms.Message;

namespace Server.Forms
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            //为了让用户和密码同时显示，不通过事件关联的方式控制显示，
            //而是通过异步事件回调的方式进行账户密码获取，见FormMain_Shown
            NovaManager.OnIntroducerRegistrationResponded += NovaManager_OnIntroducerRegistrationResponded;
            // 最小化的时候会导致客户端卡住。所以在没找到好的解决办法的时候先把最小化窗口隐藏。
            this.MinimizeBox = false;
            this.ControlBox = false;
            //NovaManager.OnNewPasswordGenerated += ServerManager_OnNewPasswordGenerated;
            NovaManager.Network.OnConnected += Network_OnConnected;
            NovaManager.Network.OnDisconnected += Network_OnDisconnected;
            NovaManager.OnAskServerShutdownMessage += NovaManager_OnAskServerShutdownMessage;
            Closed += FormMain_Closed;
            C.OnLogEvent += C_OnLogEvent;
            AddClipboardFormatListener(this.Handle);

            InitializeComponent();
            
        }

        private void NovaManager_OnAskServerShutdownMessage(object sender, Network.Messages.Nova.AskServerShutdownMessage e)
        {
            this.Close();
        }

        private void C_OnLogEvent(object sender, LogEventArgs e)
        {
            RichTextBoxLog.AppendText(string.Format(DateTime.Now.ToString() + " {0}" + Environment.NewLine, e.StrLog));
        }

        protected override void DefWndProc(ref Message m)
        {
            if (m.Msg == WM_CLIPBOARDUPDATE)
            {
                IDataObject iData = Clipboard.GetDataObject();
                if (Clipboard.ContainsFileDropList())
                {
                    FileTransferSeverManager.NotifyNewFileCanCopy(Clipboard.GetFileDropList());
                }
                else
                if (Clipboard.ContainsText())
                {
                    FileTransferSeverManager.NotifyNewTextCanCopy(Clipboard.GetText());
                }

            }
            else
            {
                base.DefWndProc(ref m);
            }
        }


        public NovaManager NovaManager => NovaServer.Instance.NovaManager;
        public LiveControlManager LiveControlManager => NovaServer.Instance.LiveControlManager;
        public FileTransferSeverManager FileTransferSeverManager => NovaServer.Instance.FileTransferSeverManager;
        public FileTransferCilentManager FileTransferCilentManager => NovaServer.Instance.FileTransferCilentManager;

        private void Network_OnDisconnected(object sender, DisconnectedEventArgs e)
        {
            LabelStatus.Set(() => LabelStatus.Text, "");
        }

        private void FormMain_Closed(object sender, EventArgs e)
        {
            LiveControlManager.Stop();
            //NovaManager.Stop();
            RemoveClipboardFormatListener(this.Handle);

        }

        private async void FormMain_Shown(object sender, EventArgs e)
        {
            this.Hide();
            var passArgs = await NovaManager.GeneratePassword();
            var regArgs = await NovaManager.RegisterWithIntroducerAsTask();
            Timer_KeepAlive.Enabled = true;
            //CheckMirrorDriverExists();

        }

        private void CheckMirrorDriverExists()
        {
            if (!LiveControlManager.Provider.DoesMirrorDriverExist())
            {
                var dialogResult =
                            MessageBox.Show(
                                "你没有安装demoforge镜像驱动器，或者你在安装后还没有重新启动您的计算机。没有镜像驱动程序，此应用程序将无法正常工作。镜像驱动程序负责通知任何改变屏幕区域的应用，通过这些改变屏幕区域应用位图。按“是”直接下载驱动程序（您之后仍然需要安装）. 你可以浏览以下网站: http://www.demoforge.com/dfmirage.htm",
                                "M镜像驱动器没有安装", MessageBoxButtons.YesNo, MessageBoxIcon.Error);

                if (dialogResult == DialogResult.Yes)
                {
                    Process.Start("http://www.demoforge.com/tightvnc/dfmirage-setup-2.0.301.exe");
                }
            }
        }


        private void Timer_KeepAlive_Tick(object sender, EventArgs e)
        {
            NovaManager.SendKeepAliveMessage();
            try
            {
                CURSORINFO vCurosrInfo;
                vCurosrInfo.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
                GetCursorInfo(out vCurosrInfo);
                if ((vCurosrInfo.flags & CURSOR_SHOWING) != CURSOR_SHOWING) return;
                Cursor vCursor = new Cursor(vCurosrInfo.hCursor);
                string strTemp = vCursor.ToString();

                LiveControlManager.SetCursor(vCursor);

            }
            catch (Exception ex)
            {
                C.LogtoTextDebug("Server", "Timer_KeepAlive_Tick", ex.Message);
                //throw;
            }
          

        }

        private void Network_OnConnected(object sender, ConnectedEventArgs e)
        {
            LabelStatus.Set(() => LabelStatus.Text, "已连接");
            //Timer_KeepAlive.Enabled = false;
        }

        private void ServerManager_OnNewPasswordGenerated(object sender, PasswordGeneratedEventArgs e)
        {
            LabelPassword.Set(() => LabelPassword.Text, e.NewPassword);
        }

        private void NovaManager_OnIntroducerRegistrationResponded(object sender,
            IntroducerRegistrationResponsedEventArgs e)
        {
            //这样就可以实现账户密码同时显示，而不是一前一后。
            LabelPassword.Text = NovaManager.Provider.ServerMachine.Password;
            LabelNovaId.Text = e.NovaId;
            TrayIcon.Text = $"本机ID {e.NovaId}";
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            C.OpenLog();
        }

        private void 显示日志ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Show();
        }

        private void SetReliableOrdered_Click(object sender, EventArgs e)
        {
            SendConfig.SetReliableOrdered();
        }

        private void SetReliableSequenced_Click(object sender, EventArgs e)
        {
            SendConfig.SetReliableSequenced();
        }

        private void SetReliableUnordered_Click(object sender, EventArgs e)
        {
            SendConfig.SetReliableUnordered();
        }

        private void SetUnreliable_Click(object sender, EventArgs e)
        {
            SendConfig.SetUnreliable();
        }

        private void SetUnreliableSequenced_Click(object sender, EventArgs e)
        {
            SendConfig.SetUnreliableSequenced();
        }
    }
}